package com.hong.taotaomall.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hong.taotaomall.dto.GoodsDto;
import com.hong.taotaomall.entity.Category;
import com.hong.taotaomall.entity.Goods;
import com.hong.taotaomall.entity.GoodsFlag;
import com.hong.taotaomall.entity.Result;
import com.hong.taotaomall.service.ICategoryService;
import com.hong.taotaomall.service.IGoodsFlagService;
import com.hong.taotaomall.service.IGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品管理 前端控制器
 * </p>
 *
 * @author hong
 * @since 2023-03-25
 */
@Slf4j
@RestController
@RequestMapping("/goods")
public class GoodsController {
    @Autowired
    private IGoodsService goodsService;

    @Autowired
    private IGoodsFlagService goodsFlagService;

    @Autowired
    private ICategoryService categoryService;

    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping
    public Result<String> save(@RequestBody GoodsDto goodsDto) {
        goodsService.saveWithFlag(goodsDto);
        String key = "goods" + goodsDto.getCategoryId() + "_1";
        redisTemplate.delete(key);
        return Result.success("新增商品成功");
    }

    @RequestMapping("/like")
    public Result<List<GoodsDto>> like(String value) {
        List<GoodsDto> dtosList ;
        LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(Goods::getName,value);
        List<Goods> list = goodsService.list(queryWrapper);

        dtosList = list.stream().map(item ->{
            GoodsDto goodsDto = new GoodsDto();
            BeanUtils.copyProperties(item,goodsDto);
            goodsDto.setValue(item.getName());
            return goodsDto;
        }).collect(Collectors.toList());

        dtosList.sort(( o1, o2) ->
                o1.getName().length() - o2.getName().length()
        );
        List<GoodsDto> goodsList = new ArrayList<>();
        if(dtosList.size() >=10){
            for (int i = 0; i < 10; i++) {
                goodsList.add(dtosList.get(i));
            }
            return Result.success(goodsList);
        }
        return Result.success(dtosList);

    }

    @GetMapping("/page")
    public Result<Page> page(int page, int pageSize, String name) {
        Page<Goods> pageInfo = new Page<>(page, pageSize);
        Page<GoodsDto> pageDto = new Page<>();



        LambdaQueryWrapper<Goods> lqw = new LambdaQueryWrapper<>();
        lqw.like(name != null, Goods::getName, name);
        lqw.orderByDesc(Goods::getUpdateTime);

        goodsService.page(pageInfo, lqw);

        BeanUtils.copyProperties(pageInfo, pageDto, "records");

        List<Goods> records = pageInfo.getRecords();
        List<Goods> list1 = goodsService.list();
        records.clear();
        Collections.shuffle(list1);
        for (int i = 0; i < pageSize; i++) {
            records.add(list1.get(i));
        }
        List<GoodsDto> list = records.stream().map(item -> {
            GoodsDto goodsDto = new GoodsDto();
            BeanUtils.copyProperties(item, goodsDto);

            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);
            if (category != null) {
                String categoryName = category.getName();
                goodsDto.setCategoryName(categoryName);
            }
            return goodsDto;

        }).collect(Collectors.toList());
        pageDto.setRecords(list);
        return Result.success(pageDto);
    }

    @GetMapping("/detail/{id}")
    public Result<GoodsDto> get(@PathVariable Long id) {
        GoodsDto goodsDto = goodsService.getByIdWithFlag(id);
        return Result.success(goodsDto);
    }

    @PutMapping
    public Result<String> update(@RequestBody GoodsDto goodsDto) {
        String key = "goods" + goodsDto.getCategoryId() + "_1";
        redisTemplate.delete(key);
        goodsService.updateWithFlag(goodsDto);
        return Result.success("修改商品成功");
    }

    @PostMapping("/status/{status}")
    public Result<String> enableAndDisable(@PathVariable int status, @RequestParam List<Long> ids) {
        LambdaQueryWrapper<Goods> lqw = new LambdaQueryWrapper<>();
        lqw.in(ids != null, Goods::getId, ids);
        List<Goods> list = goodsService.list(lqw);
        for (Goods goods : list) {
            if (goods != null) {
                goods.setStatus(status);
                goodsService.updateById(goods);
            }
        }
        return Result.success("售卖状态修改成功");
    }

    @DeleteMapping
    public Result<String> delete(@RequestParam List<Long> ids) {
        goodsService.deleteByIds(ids);
        LambdaQueryWrapper<GoodsFlag> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(GoodsFlag::getGoodsId, ids);
        goodsFlagService.remove(queryWrapper);
        return Result.success("删除商品成功");
    }

    @GetMapping("/listById/{id}&{name}")
    private Result<List<GoodsDto>> listById(@PathVariable Long id, @PathVariable String name) {
        List<GoodsDto> goodsDtoList = null;
        List<Goods> listById = null;
        LambdaQueryWrapper<Goods> queryWrapperID = new LambdaQueryWrapper<>();

        LambdaQueryWrapper<Goods> queryWrapperName = new LambdaQueryWrapper<>();
        queryWrapperName.like(Goods::getName, name);
        List<Goods> listByName = goodsService.list(queryWrapperName);

        List<Goods> All = new ArrayList<>();

        if (id == null && !(listByName.size() > 1)) {
            queryWrapperID
                    .eq(Goods::getStatus, 1)
                    .orderByDesc(Goods::getUpdateTime);
            listById = goodsService.list(queryWrapperID);
            goodsDtoList = getGoodsDtos(id, listById);
            return Result.success(goodsDtoList);
        }
        if(id != null){
            queryWrapperID
                    .eq(Goods::getCategoryId, id)
                    .eq(Goods::getStatus, 1)
                    .orderByDesc(Goods::getUpdateTime);
            listById = goodsService.list(queryWrapperID);
            All.addAll(listById);
        }

        All.addAll(listByName);
        HashSet hashSet = new HashSet(All);
        All.clear();
        All.addAll(hashSet);
        goodsDtoList = getGoodsDtos(id, All);
        return Result.success(goodsDtoList);
    }


    @GetMapping("/list")
    private Result<List<GoodsDto>> list(Goods goods) {
        List<GoodsDto> goodsDtoList = null;
        String key = "goods_" + goods.getCategoryId() + "_" + goods.getStatus();
        goodsDtoList = (List<GoodsDto>) redisTemplate.opsForValue().get(key);
        if (goodsDtoList != null) {
            return Result.success(goodsDtoList);
        }

        LambdaQueryWrapper<Goods> lqw = new LambdaQueryWrapper<>();
        lqw.eq(goods.getCategoryId() != null, Goods::getCategoryId, goods.getCategoryId())
                .orderByAsc(Goods::getSort).orderByDesc(Goods::getUpdateTime)
                .eq(Goods::getStatus, 1);
        List<Goods> goodsList = goodsService.list(lqw);
        goodsDtoList = getGoodsDtos(goods.getId(), goodsList);

        redisTemplate.opsForValue().set(key, goodsDtoList, 60, TimeUnit.MINUTES);
        return Result.success(goodsDtoList);
    }

    private List<GoodsDto> getGoodsDtos(Long id, List<Goods> All) {
        List<GoodsDto> goodsDtoList;
        goodsDtoList = All.stream().map(item -> {
            GoodsDto goodsDto = new GoodsDto();
            BeanUtils.copyProperties(item, goodsDto);

            Category category = categoryService.getById(id);
            if (category != null) {
                String categoryName = category.getName();
                goodsDto.setCategoryName(categoryName);
            }
            Long goodsId = item.getId();
            LambdaQueryWrapper<GoodsFlag> flagqRueryWrapper = new LambdaQueryWrapper<>();
            flagqRueryWrapper.eq(GoodsFlag::getGoodsId, goodsId);
            List<GoodsFlag> goodsFlagList = goodsFlagService.list(flagqRueryWrapper);
            goodsDto.setFlags(goodsFlagList);

            return goodsDto;
        }).collect(Collectors.toList());
        return goodsDtoList;
    }

}
